package com.zh.webcommon.common.filter;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.util.AntPathMatcher;

import java.io.IOException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

import static com.zh.webcommon.HeaderConst.HEADER_APP_ID;

/**
 * API调用的client验证
 *
 * client.appId:
 * client.appSecret:
 * @author ZH
 * @date 9:40 2021/11/12
 */
@Setter
@Slf4j
public class CheckClientAppFilter implements Filter {
    private final AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Value("${client.enable:false}")
    private boolean enable;
    @Value("${client.app-id:}")
    private String appId;
    @Value("${client.app-secret:}")
    private String appSecret;

    private final List<String> whileUriPatterns = new LinkedList<>();

    public CheckClientAppFilter() {
        log.info("[CheckClientAppFilter] constructor ...");
    }

    public void addWhileUriPatterns(String... uriPatterns) {
        whileUriPatterns.addAll(Arrays.asList(uriPatterns));
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        log.trace("into filter ...");
        HttpServletRequest req = (HttpServletRequest) request;

        String xAppId = req.getHeader(HEADER_APP_ID);

        //不开启检查 or 白名单直接放行
        if (!enable || isWhileUri(req.getRequestURI())) {
            chain.doFilter(request, response);
        }
        //符合appId和appSecret的也放行
        else if (Objects.equals(xAppId, appId) /*&& Objects.equals(dbAppSecret,appSecret)*/) {
            chain.doFilter(request, response);
        } else {
            log.error("无效的appId或appSecret");
            ((HttpServletResponse) response).setStatus(HttpStatus.FORBIDDEN.value());
        }

        log.trace("out of filter ...");
    }

    private boolean isWhileUri(String uri) {
        return whileUriPatterns.stream().anyMatch(pattern -> antPathMatcher.match(pattern, uri));
    }

}
